use crossbeam_deque::Injector;
use fudata::model::todo::Todo;
use fudata::model::todo::TodoType;
use log::error;
use log::trace;
use std::sync::Arc;
use anyhow::Result;
use log::info;

use crate::todo::sync_klines_todo;
use crate::todo::sync_securities_todo;

use super::RECEIVE_TIMEOUT_MS;

// Create a worker pool using Tokio
pub fn start_worker_pool(session: Arc<zenoh::Session>, num_workers: u8) -> Arc<Injector<Todo>> {
    let injector = Arc::new(Injector::new());

    // let session_clone = Arc::clone(&session);

    // Spawn workers directly using tokio::spawn
    for worker_no in 0..num_workers {
        let session_1 = Arc::clone(&session);
        let ij_clone = Arc::clone(&injector);
        tokio::spawn(async move {
            loop {
                let task = ij_clone.steal().success();
                match task {
                    Some(todo) => {
                        let session_2 = Arc::clone(&session_1);
                        // Process the todo using the handle_query function
                        let _sample = handle_sync(session_2, worker_no, todo).await;
                        // Do something with the sample...
                    }
                    None => {
                        trace!("(worker_sync) Workder[{worker_no}] steal no todo, wait {}ms", RECEIVE_TIMEOUT_MS);
                        tokio::time::sleep(
                            std::time::Duration::from_millis(RECEIVE_TIMEOUT_MS)
                        ).await;
                    }
                }
            }
        });
    }

    injector
}

// Define the handle_query function
async fn handle_sync(session: Arc<zenoh::Session>, worker_no: u8, todo: Todo) -> Result<()> {
    if let Some(type_) = &todo.type_ {
        match type_ {
            TodoType::SyncSecurities => {
                handle_sync_securites(session, worker_no, &todo).await?;
            }
            TodoType::SyncKlines => {
                handle_sync_klines(session, worker_no, &todo).await?;
            }
            _ => {
                error!("(handle_sync) unknown todo.type_:{}", type_);
            }
        }
    }

    Ok(())
}

async fn handle_sync_securites(
    session: Arc<zenoh::Session>,
    worker_no: u8,
    todo: &Todo
) -> Result<()> {
    info!("Worker[{worker_no}] (handle_sync_securites) todo={:?}", todo);
    let _ = sync_securities_todo::sync_securities(session, worker_no, todo).await;
    Ok(())
}

async fn handle_sync_klines(
    session: Arc<zenoh::Session>,
    worker_no: u8,
    todo: &Todo
) -> Result<()> {
    info!("Worker[{worker_no}] (handle_sync_klines) todo={:?}", todo);
    let _ = sync_klines_todo::sync_klines(session, worker_no, todo).await;
    Ok(())
}
